#include "Acceptor.h"
#include "TcpConnection.h"
#include "EventLoop.h"
#include "ThreadPool.h"
#include "TcpServer.h"
#include <iostream>
#include <unistd.h>

using std::cout;
using std::endl;

ThreadPool *gPool = nullptr;

class MyTask
{
public:
    MyTask(const string &msg, const TcpConnectionPtr &con)
    : _msg(msg)
    , _con(con)
    {

    }

    void process()
    {
        //可以在process函数中去进行业务逻辑的处理
        _msg;
        //接下来线程池中的线程就可以处理业务逻辑了
        //处理完成之后，需要将数据发送给Reactor/EventLoop
        //但是EventLoop自己去做其他事情去了，所以此时
        //线程池中的线程在处理好数据之后需要通知
        //Reactor/EventLoop进行接收数据
        //1、问题就是：线程池中的线程如何与Reactor之间进行通信？
        //解决方案：使用eventfd系统调用

        //此处，不能直接使用连接_con执行send函数，如果这么做
        //就表明数据是由线程池中的线程进行发送的，那么只有当
        //每个线程处理好业务逻辑之后，将数据发给客户端之后
        //线程池中的线程才能去处理第二个任务，也会导致线程池
        //中的线程发挥不了真正的作用
        _con->sendInLoop(_msg);
    }

private:
    string _msg;
    TcpConnectionPtr _con;
};

//连接建立
void onNewConnection(const TcpConnectionPtr &con)
{
    cout << con->toString() << " has connected!!!" << endl;
}

//消息到达
void onMessage(const TcpConnectionPtr &con)
{
    //接收客户端的数据
    string msg = con->receive();
    cout << ">>recv msg from client: " << msg << endl;

    MyTask task(msg, con);

    gPool->addTask(std::bind(&MyTask::process, task));
}

//连接断开
void onClose(const TcpConnectionPtr &con)
{
    cout << con->toString() << " has closed!!!" << endl;
}

void test()
{
    ThreadPool pool(4, 10);
    pool.start();//线程池中的线程会阻塞等待任务的到来
    gPool = &pool;

    TcpServer server("127.0.0.1", 8888);
    //注册回调
    server.setAllCallback(std::move(onNewConnection)
                          , std::move(onMessage)
                          , std::move(onClose));
    server.start();
}

int main(int argc, char **argv)
{
    test();
    return 0;
}

